package com.demo.seckill.service.impl;

import com.demo.seckill.service.RedPacketService;
import com.demo.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author : YU.TAN
 * @date : 2021/10/25 14:56
 */
@Service("redPacketService")
@Slf4j
public class RedPacketServiceImpl implements RedPacketService {


    @Autowired
    RedisUtil redisUtil;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer startOneSeckil(long redPacketId, int userId) {
        Integer money = 0;
        boolean lock = false;

        try {
            lock = redisUtil.tryLock(redPacketId + "", 3, 10, TimeUnit.SECONDS);
            if (lock) {
                Long restPeople = redisUtil.decr(redPacketId + "_restPeople", 1);
                if (userId % 2 == 0) {
                    int a = 1 / 0;
                }
                if (restPeople == 0) {
                    money = Integer.parseInt(redisUtil.get(redPacketId + "_money").toString());
                } else {
                    Integer restMoney = Integer.parseInt(redisUtil.get(redPacketId + "_money").toString());
                    Random random = new Random();
                    //随机范围：[1,剩余人均金额的两倍]
                    money = random.nextInt((int) (restMoney / (restPeople + 1) * 2 - 1)) + 1;
                }
                redisUtil.decr(redPacketId + "_money", money);
                /**
                 * 异步入库
                 */

                /**
                 * 异步入账
                 */
            } else {
                /**
                 * 获取锁失败，相当于抢红包失败，红包个数加一
                 */
                redisUtil.incr(redPacketId + "_num", 1);
            }

        } catch (Exception e) {
            redisUtil.incr(redPacketId + "_num", 1);
            redisUtil.incr(redPacketId + "_restPeople", 1);
            e.printStackTrace();
        } finally {
            //释放锁
            redisUtil.unLock(redPacketId + "");
        }

        return money;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer startTwoSeckil(long redPacketId, int userId) {
        Integer money = 0;
        boolean lock = false;
        try {
            /**
             * 获取锁 保证红包数量和计算红包金额的原子性操作
             */
            lock = redisUtil.tryLock(redPacketId + "", 3, 10, TimeUnit.SECONDS);
            if (lock) {
                Long restNum = redisUtil.decr(redPacketId + "_num", 1);
                if (restNum < 0) {
                    log.info("手慢了，红包派完了");
                } else {
                    if (restNum == 0) {
                        money = Integer.parseInt(redisUtil.get(redPacketId + "_money").toString());
                    } else {
                        Integer restMoney = Integer.parseInt(redisUtil.get(redPacketId + "_money").toString());
                        Random random = new Random();
                        //随机范围：[1,剩余人均金额的两倍]
                        money = random.nextInt((int) (restMoney / (restNum + 1) * 2 - 1)) + 1;
                    }
                    /**
                     * 异步入库
                     */
                    /**
                     * 异步入账
                     */
                }
            }else { /**
             * 获取锁失败相当于抢红包失败
             */
               log.info("手慢了，红包派完了");
            }
        } catch (Exception e) {
            redisUtil.incr(redPacketId + "_num", 1);
            redisUtil.incr(redPacketId + "_restPeople", 1);
            e.printStackTrace();
        } finally {
            //释放锁
            if (lock){
                redisUtil.unLock(redPacketId + "");
            }
        }
        return money;
    }
}
